import os
import yaml
from PySide6.QtCore import QObject, Signal

class Config(QObject):
    changed = Signal(str, object) # Emitted when a single value is set
    config_saved = Signal()       # Emitted after the config is saved to file

    def __init__(self, config_path=None):
        super().__init__()
        if config_path is None:
            _project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
            self.config_path = os.path.join(_project_root, 'config.yaml')
        else:
            self.config_path = config_path

        with open(self.config_path, 'r', encoding='utf-8') as f:
            self._config = yaml.safe_load(f)

    def get(self, key, default=None):
        keys = key.split('.')
        value = self._config
        try:
            for k in keys:
                value = value[k]
            return value
        except (KeyError, TypeError):
            return default

    def set(self, key, value, emit_signal=True):
        keys = key.split('.')
        d = self._config
        for k in keys[:-1]:
            d = d.setdefault(k, {})
        old_value = self.get(key)
        d[keys[-1]] = value
        if old_value != value and emit_signal:
            self.changed.emit(key, value)

    def save(self, emit_signal=True):
        with open(self.config_path, 'w', encoding='utf-8') as f:
            yaml.dump(self._config, f, indent=2, allow_unicode=True)
        if emit_signal:
            self.config_saved.emit()
    
    def reload(self):
        with open(self.config_path, 'r', encoding='utf-8') as f:
            self._config = yaml.safe_load(f)
        # For simplicity, we can emit a generic signal or handle reloads differently.
        # For now, reload won't emit the changed signal to avoid TypeErrors.
        # A better implementation might have a separate 'reloaded' signal.

    def get_service_config_by_url(self, base_url):
        """Finds the service configuration dictionary for a given base_url."""
        for provider in self.get("service_providers", []):
            if isinstance(provider, dict) and provider.get("services", {}).get("llm", {}).get("base_url") == base_url:
                return provider["services"]["llm"]
        return None

    def get_model_config_by_url(self, base_url):
        """Finds the model configuration dictionary that contains the given base_url."""
        models = self.get("translation.openai_models", [])
        if not isinstance(models, list):
            return None
        for model_config in models:
            if isinstance(model_config, dict) and model_config.get("base_url") == base_url:
                return model_config
        return None

# Global config instance
app_config = Config()
